# -*- coding: utf-8 -*-
# created on 2018/5/15
import copy
from sympy import Intersection
from mathsolver.functions.base import *


class DengChaUpdate001(BaseFunction):
    """
    更新等差数列类
    eg.在等差数列{a_{n}}中,若a_{4}=-2,a_{8}=14,则a_{11}=
    """
    def solver(self, *args):
        assert len(args) == 1
        assert isinstance(args[0], BaseSequence)
        sl = BaseShuLieDengCha(args[0].value)
        self.output.append(sl)
        return self


class DengChaUpdate002(BaseFunction):
    """
    更新等差数列类
    eg.已知各项为正数的等差数列{a_{n}}的前n项和为S_{n},a_{1}=3,a_{2}• a_{3}=S_{5}.求数列{a_{n}}的通项公式.
    """
    def solver(self, *args):
        assert len(args) == 2
        assert isinstance(args[0], BaseSequence)
        assert isinstance(args[1], str)
        sl = BaseShuLieDengCha(args[0].value)
        text = args[1]
        if text.find('正') >= 0:
            d_range = Interval(0, S.Infinity, True, True)
            sl.dRange = Intersection(sl.dRange, d_range)
            a_range = Interval(0, S.Infinity, True, True)
            sl.aRange = Intersection(sl.aRange, a_range)
        self.output.append(sl)
        return self


class DengChaUpdate003(BaseFunction):
    """
    更新等差数列类
    eg.一个等差数列的前10项之和为100,前100项之和为10,则其前110项之和为.
    """
    def solver(self, *args):
        assert len(args) == 1
        assert isinstance(args[0], str)
        text = args[0]
        assert text.find("等差数列") >= 0
        sl = BaseShuLieDengCha('a_(n)')
        self.output.append(sl)
        s_name = str('S_')
        a_name = sl.aName
        name = a_name + s_name
        sl.name = name
        sl.sName = s_name
        self.output.append(sl)
        return self


class DengChaUpdate(BaseFunction):
    CLS = [DengChaUpdate001, DengChaUpdate002, DengChaUpdate003]

    def solver(self, *args):
        r = None
        for cl in DengChaUpdate.CLS:
            try:
                r = cl(known=copy.deepcopy(self.known), verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


class DengChaSUpdate001(BaseFunction):
    """
    设数列{a_{n}},{b_{n}}都是等差数列.若a_{1}+b_{1}=7,a_{3}+b_{3}=21,则a_{5}+b_{5}=.
    """
    def solver(self, *args):
        assert len(args) == 1
        seqs = args[0].sympify()
        assert isinstance(seqs, list)
        for i, seq in enumerate(seqs):
            sl = BaseShuLieDengCha(str(seq))
            p1 = r'[a-zA-Z]_\(.*?\)'
            m1 = re.findall(p1, str(seq))
            if m1:
                for item1 in m1:
                    new_item1 = sympify(item1)
                    new_item1_name = new_item1.func
                    new_item1_index = new_item1.args[0]
                    sl.n = new_item1_index
                    p2 = r'[A-Z]_'
                    m2 = re.findall(p2, str(new_item1_name))
                    if m2:
                        sl.sName = str(new_item1_name)
                    else:
                        sl.aName = str(new_item1_name)
            self.output.append(sl)
        return self


class DengChaSUpdate002(BaseFunction):
    """
    设数列{a_{n}}和{b_{n}}都是等差数列,且a_{1}=25,b_{1}=75,a_{2}+b_{2}=100,则a_{37}+b_{37}等于(   )
    """
    def solver(self, *args):
        assert len(args) == 2
        assert isinstance(args[0], BaseSequence)
        assert isinstance(args[1], BaseSequence)
        for arg in args:
            sl = BaseShuLieDengCha(str(arg.sympify()))
            self.output.append(sl)
        return self


class DengChaSUpdate(BaseFunction):
    CLS = [DengChaSUpdate001, DengChaSUpdate002]

    def solver(self, *args):
        r = None
        for cl in DengChaSUpdate.CLS:
            try:
                r = cl(known=self.known, verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


class ShuLieTransferGongCha(BaseFunction):
    def solver(self, *args):
        if len(args) == 0:
            sls = [self.known[item] for item in self.known if isinstance(self.known[item], BaseSequence)]
            assert len(sls) == 1
            sl = sls[0]
        else:
            seq = args[0].sympify()
            seq_name = seq.func
            sl = self.search(str(seq_name))
        d_value = sl.dValue
        if d_value is None:
            d_value = 'd'
            sl.dValue = sympify('d')
        self.output.append(BaseVariable(d_value))
        return self
